/*
 *  Copyright (c) 2022 ZhuHai Jieli Technology Co.,Ltd.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/*********************************************************************************************
    *   Filename        : power_hw.h

    *   Description     :

    *   Author          : Bingquan

    *   Email           : bingquan_cai@zh-jieli.com

    *   Last modifiled  : 2018-06-04 15:44

    *   Copyright:(c)JIELI  2011-2017  @ , All Rights Reserved.
*********************************************************************************************/
#ifndef _POWER_HW_H_
#define _POWER_HW_H_

#include "typedef.h"
#include "power/p33.h"
#include "list.h"

#define LP_KST              (JL_P33->PMU_CON  |= BIT(4))

#define LP_OSC_DIV(z)       ((z) > 1000000L ? 64 : 1)
#define LP_FREQ(z)          ((z) / LP_OSC_DIV(z))
#define LP_nS(z)            (1000000000L / LP_FREQ(z))

#define POFF_EN             0

// stable time(uS)
#define TSTB0               10L
#define TSTB1               10L
#define TSTB2               10L
#define TSTB3               10L
#define TSTB4               500L
#define TSTB5               1000L   // OSC wait timeout
#define TSTB6               100L    // Pll wait stable timeout
#define LP_TN(x, z)          (((x) * 1000L) / LP_nS(z))

#define NSTB0(z)            LP_TN(TSTB0, (z))
#define NSTB1(z)            LP_TN(TSTB1, (z))
#define NSTB2(z)            LP_TN(TSTB2, (z))
#define NSTB3(z)            LP_TN(TSTB3, (z))
#define NSTB4(z)            LP_TN(TSTB4, (z))
#define NSTB5(z)            LP_TN(TSTB5, (z))
#define NSTB6(z)            LP_TN(TSTB6, (z))

static inline u8 LP_NK(u16 x)
{
    u16 i = 15;

    for (i = 15; i > 1 ; i--) {
        if (x > ((u16)(1 << (i - 1)))) {
            return i;
        }
    }

    if (x > 1) {
        return 1;
    }

    return 0;
}

#define KSTB0(z)   (LP_NK(NSTB0(z)))
#define KSTB1(z)   (LP_NK(NSTB1(z)))
#define KSTB2(z)   (LP_NK(NSTB2(z)))
#define KSTB3(z)   (LP_NK(NSTB3(z)))
#define KSTB4(z)   (LP_NK(NSTB4(z)))
#define KSTB5(z)   (LP_NK(NSTB5(z)))
#define KSTB6(z)   (LP_NK(NSTB6(z)))

// P33
#define ana_con0_init                           \
    ((1 << 7) /* RC EN        1bit RW  */ | \
    (1 << 6) /* MRTC33       1bit RW  */ | \
    (1 << 5) /* PW GATE      1bit RW  */ | \
    (1 << 4) /* MLDO33       1bit RW  */ | \
    (0 << 3) /*              1bit RW  */ | \
    (1 << 2) /* LDO 15       1bit RW  */ | \
    (1 << 1) /*              1bit RW  */ | \
    (1 << 0)) /* LDO 1512     1bit RW  */

#define ana_con1_init                           \
    ((0 << 7) /* ILBTLDO_EN   1bit RW  */ | \
    (0 << 6) /* MRTC_HW_SEL  1bit RW  */ | \
    (0 << 5) /* WVDDIO       1bit RW  */ | \
    (0 << 4) /* WBTLDO       1bit RW  */ | \
    (0 << 3) /* WLDO06       1bit RW  */ | \
    (1 << 2) /* ILVDD_EN     1bit RW  */ | \
    (1 << 1) /* WLDO12       1bit RW  */ | \
    (0 << 0)) /* MRTC_SW_EN   1bit RW  */

#define ana_con2_init                           \
    ((2 << 5) /* WVBG LEVEL   3bit RW  */ | \
    (1 << 4) /* D2SH EN      1bit RW  */ | \
    (1 << 3) /* VCM DET      1bit RW  */ | \
    (2 << 0)) /* RTC LEVEL    3bit RW  */

#define ana_con3_init                           \
    (2 << 0) /* WVBG HD      2bit RW  */

#define chg_con_init                            \
    ((0 << 4) /* LEVEL        4bit RW  */ | \
    (1 << 2) /* CURRENT      2bit RW  */ | \
    (1 << 1) /* CHG DET EN   1bit RW  */ | \
    (1 << 0)) /* CHG EN       1bit RW  */

#define ana_keep_init                           \
    ((0 << 7) /* RC EN KEEP   1bit RW  */ | \
    (0 << 6) /* MRTC33 KEEP  1bit RW  */ | \
    (0 << 5) /* PW GATE KEEP 1bit RW  */ | \
    (0 << 4) /* MLDO33 KEEP  1bit RW  */ | \
    (0 << 3) /* DCDC 15 KEEP 1bit RW  */ | \
    (0 << 2) /* LDO 15 KEEP  1bit RW  */ | \
    (0 << 1) /* MVBG KEEP    1bit RW  */ | \
    (0 << 0)) /* LDO 1512 KEEP1bit RW  */

#define vld_keep_init                           \
    ((0 << 2) /* OSH DIFF KEEP1bit RW  */ | \
    (0 << 1) /* WKUP KEEP    1bit RW  */ | \
    (1 << 0)) /* CLK KEEP     1bit RW  */

#define pwm_con0_init                           \
    ((0 << 4) /* CLK PDIV     4bit RW  */ | \
    (3 << 2) /* CK SEL       3bit RW  */ | /* 0:RC 1:BT 2:RTCL 3:LRC */\
    (0 << 1) /* BREATHE      1bit RW  */ | \
    (0 << 0)) /* PWM EN       1bit RW  */

#define pwm_con1_init                           \
    ((1 << 7) /* PWM DUTY2 EN 1bit RW  */ | \
    (1 << 6) /* PWM DUTY1 EN 1bit RW  */ | \
    (1 << 5) /* PWM DUTY0 EN 1bit RW  */ | \
    (1 << 4) /* OUT LOGIC    1bit RW  */ | /* 0 is or; 1 is and */ \
    (2 << 2) /* SHIFT DUTY   2bit RW  */ | \
    (1 << 1) /* PWM EDGE1    1bit RW  */ | \
    (0 << 0)) /* PWM EDGE0    1bit RW  */

// --------------------------------------------- //
#define PD_CON_INIT_RTC                         \
    ((0 << 15) /*              1bit RW  */ | \
    (0 << 14) /* BGB keep     1bit RW  */ | \
    (1 << 13) /* LPM WKUP SEL 1bit RW  */ | \
    (0 << 12) /*              1bit RW  */ | \
    (1 << 11) /* PLL keep     1bit RW  */ | \
    (0 << 10) /* BT OSC keep  1bit RW  */ | \
    (0 << 9 ) /*              1bit RW  */ | \
    (0 << 8 ) /* PLL CLK keep 1bit RW  */ | \
    (0 << 7 ) /* PMU PND1     1bit RO  */ | \
    (0 << 5 ) /* PMU PND0     1bit WO  */ | \
    (0 << 4 ) /*              1bit RO  */ | \
    (1 << 3 ) /* PMU IE1      1bit RO  */ | \
    (1 << 2 ) /* PMU IE0      1bit RO  */ | \
    (0 << 1 ) /*              1bit RO  */ | \
    (0 << 0 )) /*              1bit RW  */

#define PD_CON_INIT_BT                          \
    ((0 << 15) /*              1bit RW  */ | \
    (0 << 14) /* BGB keep     1bit RW  */ | \
    (1 << 13) /* LPM WKUP SEL 1bit RW  */ | \
    (0 << 12) /*              1bit RW  */ | \
    (0 << 11) /* PLL keep     1bit RW  */ | \
    (1 << 10) /* BT OSC keep  1bit RW  */ | \
    (0 << 9 ) /*              1bit RW  */ | \
    (0 << 8 ) /* PLL CLK keep 1bit RW  */ | \
    (0 << 7 ) /* PMU PND1     1bit RO  */ | \
    (0 << 5 ) /* PMU PND0     1bit WO  */ | \
    (0 << 4 ) /*              1bit RO  */ | \
    (1 << 3 ) /* PMU IE1      1bit RO  */ | \
    (1 << 2 ) /* PMU IE0      1bit RO  */ | \
    (0 << 1 ) /*              1bit RO  */ | \
    (0 << 0 )) /*              1bit RW  */

#define PD_CON_INIT_LRC                         \
    ((0 << 15) /*              1bit RW  */ | \
    (0 << 14) /* BGB keep     1bit RW  */ | \
    (1 << 13) /* LPM WKUP SEL 1bit RW  */ | \
    (0 << 12) /*              1bit RW  */ | \
    (0 << 11) /* PLL keep     1bit RW  */ | \
    (0 << 10) /* BT OSC keep  1bit RW  */ | \
    (0 << 9 ) /*              1bit RW  */ | \
    (0 << 8 ) /* PLL CLK keep 1bit RW  */ | \
    (0 << 7 ) /* PMU PND1     1bit RO  */ | \
    (0 << 5 ) /* PMU PND0     1bit WO  */ | \
    (0 << 4 ) /*              1bit RO  */ | \
    (1 << 3 ) /* PMU IE1      1bit RO  */ | \
    (1 << 2 ) /* PMU IE0      1bit RO  */ | \
    (0 << 1 ) /*              1bit RO  */ | \
    (0 << 0 )) /*              1bit RW  */

#define PD_CON0_INIT                            \
    ((0 << 7) /*                       */ | \
    (0 << 6) /*                       */ | \
    (0 << 5) /* PD_RUN FLAG  1bit RO  */ | \
    (0 << 4) /* WL SETL TMR  1bit RW  */ | \
    (2 << 2) /* DIS EN       2bit RW  */ | \
    (0 << 1) /* PD MD        1bit RW  */ /* 0:Power down / 1:Power off */ | \
    (1 << 0)) /* PD_EN        1bit RW  */

#define PD_CON0_POWEROFF                        \
    ((0 << 7) /*                       */ | \
    (0 << 6) /*                       */ | \
    (0 << 5) /* PD_RUN FLAG  1bit RO  */ | \
    (0 << 4) /* WL SETL TMR  1bit RW  */ | \
    (2 << 2) /* DIS EN       2bit RW  */ | \
    (1 << 1) /* PD MD        1bit RW  */ /* 0:Power down / 1:Power off */ | \
    (1 << 0)) /* PD_EN        1bit RW  */

#define PD_CON1_INIT                            \
    ((0 << 7) /* POR FLAG     1bit RO  */ | \
    (1 << 6) /* CLR POR PND  1bit RW  */ | \
    (0 << 4) /* CK DIV       2bit RW  */ /* 0:div0 1:div4 2:div16 3:div64 */  | \
    (0 << 3) /* PU SLOW      1bit RW  */ | \
    (4 << 0)) /* CK SEL       3bit RW  */ /* 0:RC 1:BT 2:RTCH 3:RTCL 4:LRC */

#define PD_CON1_INIT_BT                            \
    ((0 << 7) /* POR FLAG     1bit RO  */ | \
    (1 << 6) /* CLR POR PND  1bit RW  */ | \
    (3 << 4) /* CK DIV       2bit RW  */ /* 0:div0 1:div4 2:div16 3:div64 */  | \
    (0 << 3) /* PU SLOW      1bit RW  */ | \
    (1 << 0)) /* CK SEL       3bit RW  */ /* 0:RC 1:BT 2:RTCH 3:RTCL 4:LRC */

#define PD_CON1_INIT_RTCL                            \
    ((0 << 7) /* POR FLAG     1bit RO  */ | \
    (1 << 6) /* CLR POR PND  1bit RW  */ | \
    (0 << 4) /* CK DIV       2bit RW  */ /* 0:div0 1:div4 2:div16 3:div64 */  | \
    (0 << 3) /* PU SLOW      1bit RW  */ | \
    (3 << 0)) /* CK SEL       3bit RW  */ /* 0:RC 1:BT 2:RTCH 3:RTCL 4:LRC */

#define PD_CON1_INIT_LRC_32K                         \
    ((0 << 7) /* POR FLAG     1bit RO  */ | \
    (1 << 6) /* CLR POR PND  1bit RW  */ | \
    (0 << 4) /* CK DIV       2bit RW  */ /* 0:div0 1:div4 2:div16 3:div64 */  | \
    (0 << 3) /* PU SLOW      1bit RW  */ | \
    (4 << 0)) /* CK SEL       3bit RW  */ /* 0:RC 1:BT 2:RTCH 3:RTCL 4:LRC */

#define PD_CON2_INIT                            \
    ((0 << 4) /* SOFT USE     8bit RW  */ | \
    (0 << 3) /* SPI BPORT    1bit RW  */ | \
    (0 << 2) /* SPI APORT    1bit RW  */ | \
    (3 << 0)) /* BT_FAST      2bit RW  */ /* 0:NO CLK 1:BT 3ms 2:BT 1ms 3:RTC  */

#define PD_CON3_INIT                  0

#define PD_CON4_INIT_TMR1_RTC                   \
    ((0 << 7) /*              1bit RW  */ | \
    (0 << 6) /* HW_KST TMR1  1bit RW  */ | \
    (0 << 5) /* HW_KST TMR0  1bit RW  */ | \
    (0 << 4) /* HW_KST LP    1bit RW  */ | \
    (0 << 3) /*              1bit RW  */ | \
    (1 << 2) /* SW_KST TMR1  1bit RW  */ | \
    (0 << 1) /* SW_KST TMR0  1bit RW  */ | \
    (0 << 0)) /* SW_KST LP    1bit RW  */

#define PD_CON4_INIT_TMR0                       \
    ((0 << 7) /*              1bit RW  */ | \
    (0 << 6) /* HW_KST TMR1  1bit RW  */ | \
    (1 << 5) /* HW_KST TMR0  1bit RW  */ | \
    (0 << 4) /* HW_KST LP    1bit RW  */ | \
    (0 << 3) /*              1bit RW  */ | \
    (0 << 2) /* SW_KST TMR1  1bit RW  */ | \
    (0 << 1) /* SW_KST TMR0  1bit RW  */ | \
    (0 << 0)) /* SW_KST LP    1bit RW  */

#define PD_CON4_INIT_TMR1                       \
    ((0 << 7) /*              1bit RW  */ | \
    (0 << 6) /* HW_KST TMR1  1bit RW  */ | \
    (0 << 5) /* HW_KST TMR0  1bit RW  */ | \
    (0 << 4) /* HW_KST LP    1bit RW  */ | \
    (0 << 3) /*              1bit RW  */ | \
    (0 << 2) /* SW_KST TMR1  1bit RW  */ | \
    (1 << 1) /* SW_KST TMR0  1bit RW  */ | \
    (0 << 0)) /* SW_KST LP    1bit RW  */

#define PD_CON4_INIT_LP_KST                     \
    ((0 << 7) /*              1bit RW  */ | \
    (0 << 6) /* HW_KST TMR1  1bit RW  */ | \
    (0 << 5) /* HW_KST TMR0  1bit RW  */ | \
    (0 << 4) /* HW_KST LP    1bit RW  */ | \
    (0 << 3) /*              1bit RW  */ | \
    (0 << 2) /* SW_KST TMR1  1bit RW  */ | \
    (0 << 1) /* SW_KST TMR0  1bit RW  */ | \
    (1 << 0)) /* SW_KST LP    1bit RW  */

#define PD_CON5_INIT                  0

#define PRP_INIT        0x0102

#define PD_PRP0_INIT                           \
    ((PRP_INIT >>  8) & 0xff) /* PRP[15:08]   8bit WO */
#define PD_PRP1_INIT                           \
    ((PRP_INIT )      & 0xff) /* PRP[07:00]   8bit WO */

#define pd_stb0_stb1_init                       \
    ((2 << 4) /* STB1 SET     4bit RW  */ | \
    (2 << 0)) /* STB0 SET     4bit RW  */

#define pd_stb2_stb3_init                         \
    ((0x1 << 4) /* STB3 SET     4bit RW  */ | \
    (2 << 0))   /* STB2 SET     4bit RW  */

#define pd_stb4_stb5_init                         \
    ((0x3 << 4) /* STB5 SET     4bit RW  */ | \
    (2 << 0))   /* STB4 SET     4bit RW  */

#define pd_stb6_init                            \
    (2 << 0) /* STB6 SET     4bit RW  */

#define PD_STB0_STB1_INIT(a , b)                       \
    ((a << 4) /* STB1 SET     4bit RW  */ | \
    (b << 0)) /* STB0 SET     4bit RW  */

#define PD_STB2_STB3_INIT(a, b)                         \
    ((a << 4) /* STB3 SET     4bit RW  */ | \
    (b << 0)) /* STB2 SET     4bit RW  */

#define PD_STB4_STB5_INIT(a, b)                         \
    ((a << 4) /* STB5 SET     4bit RW  */ | \
    (b << 0)) /* STB4 SET     4bit RW  */

#define PD_STB6_INIT(a)                            \
     (a << 0) /* STB6 SET     4bit RW  */

#define RSC0_INIT        0x00001460

#define pd_RSC00_init                            \
    ((RSC0_INIT >> 24) & 0xff) /* RSC[31:24]   8bit WO */
#define pd_RSC01_init                            \
    ((RSC0_INIT >> 16) & 0xff) /* RSC[23:16]   8bit WO */
#define pd_RSC02_init                            \
    ((RSC0_INIT >>  8) & 0xff) /* RSC[15:08]   8bit WO */
#define pd_RSC03_init                            \
    ((RSC0_INIT )      & 0xff) /* RSC[07:00]   8bit WO */

#define PRD0_INIT        0x00001490

#define pd_PRD00_init                            \
    ((PRD0_INIT >> 24) & 0xff) /* PRD[31:24]   8bit WO */
#define pd_PRD01_init                            \
    ((PRD0_INIT >> 16) & 0xff) /* PRD[23:16]   8bit WO */
#define pd_PRD02_init                            \
    ((PRD0_INIT >>  8) & 0xff) /* PRD[15:08]   8bit WO */
#define pd_PRD03_init                            \
    ((PRD0_INIT )      & 0xff) /* PRD[07:00]   8bit WO */

#define RSC1_INIT        0x00000460

#define pd_RSC10_init                            \
    ((RSC1_INIT >> 24) & 0xff) /* RSC[31:24]   8bit WO */
#define pd_RSC11_init                            \
    ((RSC1_INIT >> 16) & 0xff) /* RSC[23:16]   8bit WO */
#define pd_RSC12_init                            \
    ((RSC1_INIT >>  8) & 0xff) /* RSC[15:08]   8bit WO */
#define pd_RSC13_init                            \
    ((RSC1_INIT )      & 0xff) /* RSC[07:00]   8bit WO */

#define PRD1_INIT        0x00000490

#define pd_PRD10_init                            \
    ((PRD1_INIT >> 24) & 0xff) /* PRD[31:24]   8bit WO */
#define pd_PRD11_init                            \
    ((PRD1_INIT >> 16) & 0xff) /* PRD[23:16]   8bit WO */
#define pd_PRD12_init                            \
    ((PRD1_INIT >>  8) & 0xff) /* PRD[15:08]   8bit WO */
#define pd_PRD13_init                            \
    ((PRD1_INIT )      & 0xff) /* PRD[07:00]   8bit WO */

#define pd_tmr1_rtc_init                            \
    ((0 << 7) /* TIMEOUT FLAG 1bit RO  */ | \
    (1 << 6) /* CLR TO PND   1bit RW  */ | \
    (0 << 5) /* WK PND       1bit RW  */ | \
    (0 << 4) /* CLR WK PND   1bit RW  */ | \
    (1 << 3) /* TIMEOUT IE   1bit RW  */ | \
    (0 << 2) /* RECOVER IE   1bit RW  */ | \
    (1 << 1) /* CONTINUE     1bit RW  */ | \
    (1 << 0)) /* EN           1bit RW  */

#define pd_tmr0_init                            \
    ((0 << 7) /* TIMEOUT FLAG 1bit RO  */ | \
    (1 << 6) /* CLR TO PND   1bit RW  */ | \
    (0 << 5) /* WK PND       1bit RW  */ | \
    (0 << 4) /* CLR WK PND   1bit RW  */ | \
    (1 << 3) /* TIMEOUT IE   1bit RW  */ | \
    (1 << 2) /* RECOVER IE   1bit RW  */ | \
    (0 << 1) /* CONTINUE     1bit RW  */ | \
    (1 << 0)) /* EN           1bit RW  */

#define pd_tmr1_init                            \
    ((0 << 7) /* TIMEOUT FLAG 1bit RO  */ | \
    (1 << 6) /* CLR TO PND   1bit RW  */ | \
    (0 << 5) /* WK PND       1bit RW  */ | \
    (1 << 4) /* CLR WK PND   1bit RW  */ | \
    (1 << 3) /* TIMEOUT IE   1bit RW  */ | \
    (1 << 2) /* RECOVER IE   1bit RW  */ | \
    (0 << 1) /* CONTINUE     1bit RW  */ | \
    (1 << 0)) /* EN           1bit RW  */

#define PD_LP0_CNT_READ                         \
    ((0 << 7) /*              1bit RO  */ | \
    (0 << 6) /*              1bit RW  */ | \
    (0 << 5) /*              1bit RW  */ | \
    (0 << 4) /*              1bit RW  */ | \
    (0 << 3) /*              1bit RW  */ | \
    (0 << 2) /* TMR1 CNT READ1bit WO  */ | \
    (1 << 1) /* TMR0 CNT READ1bit WO  */ | \
    (0 << 0)) /* STC READ     1bit WO  */

#define PD_LP0_STC_READ                         \
    ((0 << 7) /*              1bit RO  */ | \
    (0 << 6) /*              1bit RW  */ | \
    (0 << 5) /*              1bit RW  */ | \
    (0 << 4) /*              1bit RW  */ | \
    (0 << 3) /*              1bit RW  */ | \
    (0 << 2) /* TMR1 CNT READ1bit WO  */ | \
    (0 << 1) /* TMR0 CNT READ1bit WO  */ | \
    (1 << 0)) /* STC READ     1bit WO  */

#define PD_LP1_CNT_READ                         \
    ((0 << 7) /*              1bit RO  */ | \
    (0 << 6) /*              1bit RW  */ | \
    (0 << 5) /*              1bit RW  */ | \
    (0 << 4) /*              1bit RW  */ | \
    (0 << 3) /*              1bit RW  */ | \
    (1 << 2) /* TMR1 CNT READ1bit WO  */ | \
    (0 << 1) /* TMR0 CNT READ1bit WO  */ | \
    (0 << 0)) /* STC READ     1bit WO  */

#define pd_mstm_read                            \
    (0 << 0) /* MSTM READ    4bit RO  */ |

#define pd_ivs_read                             \
    ((0 << 7) /* PWR VLD      1bit RO  */ | \
    (0 << 6) /* PW DIS       1bit RO  */ | \
    (0 << 5) /* RST MASK     1bit RO  */ | \
    (0 << 4) /* MLD012 SW    1bit RO  */ | \
    (0 << 3) /* ALL VLD      1bit RO  */ | \
    (0 << 2) /* ANA VLD      1bit RO  */ | \
    (0 << 1) /* CLK VLD      1bit RO  */ | \
    (0 << 0)) /* MVRAM PWR    1bit RO  */

#define pd_ivs_set                              \
    ((0 << 7) /* PWR VLD  EN  1bit WO  */ | \
    (0 << 6) /* PW DIS EN    1bit WO  */ | \
    (0 << 5) /* RST MASK     1bit WO  */ | \
    (0 << 4) /* MLD012 SW ON 1bit WO  */ | \
    (0 << 3) /* ALL VLD EN   1bit WO  */ | \
    (0 << 2) /* ANA VLD EN   1bit WO  */ | \
    (0 << 1) /* CLK VLD EN   1bit WO  */ | \
    (0 << 0)) /* MVRAM PWR EN 1bit WO  */

#define pd_ivs_clr                              \
    ((0 << 7) /* PWR VLD  DIS 1bit WO  */ | \
    (0 << 6) /* PW DIS DIS   1bit WO  */ | \
    (0 << 5) /* RST MASK     1bit WO  */ | \
    (0 << 4) /* MLD012 SW OFF1bit WO  */ | \
    (0 << 3) /* ALL VLD DIS  1bit WO  */ | \
    (0 << 2) /* ANA VLD DIS  1bit WO  */ | \
    (0 << 1) /* CLK VLD DIS  1bit WO  */ | \
    (0 << 0)) /* MVRAM PWR DIS1bit WO  */

#define pd_wldo12_auto_init                     \
    (5 << 5) /* WLDO PRD     3bit RW  */

#define pd_wldo06_auto_init                     \
    ((0 << 5) /* WLDO LVL LOW 3bit RW  */ | \
    (1 << 4) /* WLDO EN      1bit RW  */ | \
    (7 << 0)) /* WLDO LEVEL   3bit RW  */

#define LRC_CON0_INIT                                     \
    ((0 << 7) /* RC32K_RNPS_S0_33v              */ |\
    (1 << 6) /* RC32K_RPPS_S2_33v              */ |\
    (0 << 5) /* RC32K_RPPS_S1_33v              */ |\
    (0 << 4) /* RC32K_RPPS_S0_33v              */ |\
    (0 << 3) /*                                */ |\
    (0 << 2) /*                                */ |\
    (0 << 1) /* RC32K_RN_TRIM_33v              */ |\
    (1 << 0)) /* RC32K_EN_33v                   */

#define LRC_CON1_INIT                                     \
    ((0 << 7) /*                                */ |\
    (0 << 6) /*                                */ |\
    (1 << 5) /* RC32K_LDO_S0_33v               */ |\
    (1 << 4) /* RC32K_CAP_S2_33v               */ |\
    (1 << 3) /* RC32K_CAP_S1_33v               */ |\
    (1 << 2) /* RC32K_CAP_S0_33v               */ |\
    (1 << 1) /* RC32K_RNPS_S2_33v              */ |\
    (0 << 0)) /* RC32K_RNPS_S1_33v              */

#define ana_con7_init                                     \
    ((0 << 7) /*                                */ |\
    (0 << 6) /* DCDC_OSC_S2_33V                */ |\
    (1 << 5) /* DCDC_OSC_S1_33V                */ |\
    (1 << 4) /* DCDC_OSC_S0_33V                */ |\
    (1 << 3) /* DCDC_DUTY_S1_33V               */ |\
    (0 << 2) /* DCDC_DUTY_SO_33V               */ |\
    (0 << 1) /* DCDC_BIAS_HD1_33V              */ |\
    (1 << 0)) /* DCDC_BIAS_HD0_33V              */

enum {
    R3_WKUP_SRC_ALM = 0,
    R3_WKUP_SRC_FLAG,
    R3_WKUP_SRC_PORT = 3,
    R3_WKUP_SRC_512HZ,
    R3_WKUP_SRC_64HZ,
    R3_WKUP_SRC_2HZ,
    R3_WKUP_SRC_1HZ,
};

enum {
    P3_WKUP_SRC_PCNT_OVF = 0,
    P3_WKUP_SRC_EDGE,
    P3_WKUP_SRC_SUB = 3,
    P3_WKUP_SRC_VDD50_LVD,
    P3_WKUP_SRC_CHG = 6,
    P3_WKUP_SRC_WDT_INT,
};

enum {
    P3_WKUP_SUB_LVCMP = 0,
    P3_WKUP_SUB_LDO5V,
    P3_WKUP_SUB_L5DEM,
};

#define REGS_NUM        60

#define BT_REGS_NUM     2

#define RTC_REGS_NUM    3

struct power_driver_hdl {
    u8 mode;
    u8 delay_usec;
    u8 charge_sw;
    u8 keep_osci_flag;
    u8 osc_type;
    u8 last_osc_type;
    u8 default_osc_type;
    u8 pwr_mode;
    u8 btosc_disable;

    u8 pd_wdvdd_lev;
    u8 dcdc_port;

    u32 regs[REGS_NUM];
    u32 bt_regs[BT_REGS_NUM];
    u32 rtc_regs[RTC_REGS_NUM];
    u32 osc_hz;
    u32 btosc_hz;
    u32 osc_delay_us;
    u16 dcdc_delay_us;
    u32 Tosc;
    u8 kstb0;
    u8 kstb1;
    u8 kstb2;
    u8 kstb3;
    u8 kstb4;
    u8 kstb5;
    u8 kstb6;

    u8 vddiow_lev;
    u8 vddiom_lev;

    void (*powerdown_enter)(u8 step);
    void (*powerdown_exit)(u32);

    void (*poweroff_enter)(void);
    void (*poweroff_exit)(u32);

    void (*soft_poweroff_enter)(void);
};
struct power {
    struct list_head entry;
    void *priv;
    const struct low_power_operation *ops;
};

struct low_power_group {
    /* struct list_head head_on; */
    struct list_head request_head;
    u32 timeout;
};

struct power_hdl {
    struct low_power_group group0;  // bluetooth
    struct low_power_group group1;  // System
    u8 mode;
    u32 Tcke;
    u32 Tprp;
    u32 reserve_time;
    u32 recover_time_us;
    u32 recover_total_time;

    u8 pending;
    u8 fatal_error;
    u8 lock;
    u8 is_poweroff;
    u8 config;
    u8 keep_dacvdd;
    u8 vddio_keep;
    u8 vdc13_keep;
    u8 user_nv_timer_en;

    u32 softoff_wakeup_t;

    u16 nv_timer_interval;
    u32 vir_rtc_trim_time;

    void (*callback)(u32);

    u8 rtc_clk;
    u8 lvd_keep;

    struct power_driver_hdl hw;
};

/* ----------------------------------------------------------- */

// rom function declare
u32 maskrom_version(void);
void nvram_jumpaddr_set(u32 addr);
void nvram_jumpaddr_clear(void);
void nvram_signature_clear(void);
void nvram_signature_set(void);
BOOL nvram_signature_verify(void);
void exception_init(void);
void exception_init(void);
void softoff_keep_vir_rtc(void);

u32 __tcnt_us_lrc(u32 x);

u32 __tcnt_us(u32 x);

u32 __tcnt_ms(u32 x);

u32 __tus_cnt(u32 x);

u32 __tcnt_us_no_carry(u32 x);

void __low_power_resume(u32 usec);

void __low_power_sys_resume(u32 usec);

void __hw_trim_dvdd(void);

void dsp_dvdd_set(u16 voltage);

void sys_dvdd_set(u16 voltage);

void vdc13_set(u16 voltage);

extern struct power_hdl low_power_hdl;

void power_reset_close(void);

void latch_reset(void);
//*********************************************************************************//
//                                                                                 //
//                               end of this module                                //
//                                                                                 //
//*********************************************************************************//

#endif
